<template>
  <div style="overflow: hidden;" ref="tableContainer">
      <table style="width: 100%;height: 100%;" class="tableEle" ref="tableEle">
          <thead style="z-index: 2;position: relative;">
            <tr class="title" ref="titlerow">
                <th v-if="showIndex" style="width: 1.2em;"> </th>
                <th v-if="showCheckBox" style="width: 1.2em;"> </th>
                <th v-for="(column,index) in columns" :key="index" :width="column.width">
                {{column.title}}
                </th>
                <th v-if="isVerticalScroll" style="width: 0.3em;">
                    <div  ref="scrollbar" class="scrollbar-right">
                        <ScrollBar :max="data.length" :value.sync="showStartIndex" :rangeValue="this.shownums"></ScrollBar>
                    </div>
                </th>
            </tr>
          </thead>

         <tbody ref="tbody" style="z-index: 0;position: relative;">
            <tr v-for="(item,indexR) in localData" :key="indexR" class="rows" :class="getRowStyle(item,indexR)" :height='rowHeight' @click="selectItem(item)">
                <td v-if="showIndex">{{ data.indexOf(item)+1 }}</td>
                <td v-if="showCheckBox"><CheckBox :value.sync="item.__checked" @checked="checkItem(item)"></CheckBox></td>
                    
                <td v-for="(column,indexC) in columns" :key="indexC" @dblclick="(e)=>dblclick(e,item,column,indexC)" >
                    <div>
                        <div v-if="typeof (item[indexC])!='undefined' && item[indexC].__editing" style="height: 80%;width:100% ">
                            <JSelect v-if="column.type == 'select'" :options="column.options" v-model="item[column.key]" @blur='blur(item,column,indexC)' style="height: 100%;line-height: 100%; "></JSelect>
                            <JInput v-else v-model="item[column.key]" @blur='blur(item,column,indexC)' @valueChange="(val)=>item[column.key] = val" style="height: 100%;line-height: 100%;"></JInput>
                        </div>
                        <div v-else>{{item[column.key]}}
                        </div>
                    </div>            
                </td>
            </tr>            
         </tbody>
      </table>
  </div>
</template>

<script>
import Vue from 'vue';
import CheckBox from '../CheckBox/CheckBox.vue';
import JInput from '../JInput/JInput.vue';
import JSelect from '../JSelect/JSelect.vue';
import ScrollBar  from '../ScrollBar/ScrollBar.vue';

export default {
    components:{
        CheckBox,
        JInput,
        JSelect,
        ScrollBar
    },
    props:{
        data:{
            type:Array,
            default:()=>{
                return [];
            }
        },
        columns:{
            type:Array,
            default:()=>{
                return [];
            }
        },
        showCheckBox:{
            type:Boolean,
            default:false
        },
        showIndex:{
            type:Boolean,
            default:false
        },
        isMultiSelect:{
            type:Boolean,
            default:false
        },
        rowClass:{
            type: Function,
            default: undefined
        },
        rowHeight:{
            type:Number,
            default:30
        }
    },
    data(){
        return {
            localData:[],
            isVerticalScroll: true,
            shownums:this.data.length,
            showStartIndex: 0, 
        }
    },
    created(){

    },
    mounted(){
        const debounce = this.debounce;
        const _ResizeObserver = window.ResizeObserver;
        //防止抖动的 ResizeObserver，不然会导致报错
        const MyObserver = class ResizeObserver extends _ResizeObserver {
            constructor(callback) {
                callback = debounce(callback, 100);
                super(callback);
            }
        }
        const that = this;
        const observer = new MyObserver(entries => {
            this.updateScrollBar();
        });
        observer.observe(this.$refs.tableContainer);
        this.$refs.tableContainer.addEventListener('wheel', function(event) {
            event.preventDefault();        
            if (event.deltaY > 0) {
                if(that.showStartIndex + that.shownums < that.data.length)
                {
                    that.showStartIndex++
                }
            } else {
                if(that.showStartIndex > 0)
                {
                    that.showStartIndex--
                }
            }
        });
    },
    watch:{
        data(){
           this.localData = this.data//.slice(this.showStartIndex,this.showStartIndex+this.shownums)
        },
        // isVerticalScroll(val){
        //     if(val){
        //         this.updateScrollBar();
        //     }
        // },
        showStartIndex(val){
            console.log('showStartIndex',val,this.shownums)
            this.localData = this.data.slice(val,val+this.shownums)
            const tbody  = this.$refs.tbody;
            if(this.showStartIndex + this.shownums == this.data.length)
            {
                const tableContainer =  this.$refs.tableContainer
                if(tbody.getBoundingClientRect().bottom>tableContainer.getBoundingClientRect().bottom)
                {
                   tbody.style.transform = 'translateY(-' + (tbody.getBoundingClientRect().bottom-tableContainer.getBoundingClientRect().bottom) + 'px)'
                }else
                {
                    tbody.style.transform = ''
                }
            }else
            {
                tbody.style.transform = ''
            }
        }
    },
    methods:{
        debounce(fn, delay){
            let timer
            return (...args) => {
                if (timer) {
                    clearTimeout(timer)
                }
                timer = setTimeout(() => {
                    fn(...args)
                }, delay)
            }
        },
        getData(){
            return this.localData;
        },
        computeWidth(){
            // let emptyColumns =  columns.filter(t=>{
            //     typeof t.width == 'undefined' || t.width == '' || t.width == null
            // })
            // let notEmptyColumns = columns.filter(t=>{
            //     typeof t.width == 'undefined' && t.width !='' && t.width != null
            // })
            // let leftwidth =''
            // notEmptyColumns.forEach(t=>{
            //     leftwidth += ' - '+t.width;
            // })
        },
        selectItem(item){
            Vue.set(item,'__selected',true);            
            if(!this.isMultiSelect){
                this.data.forEach(t=>{
                    if(t!=item){
                        Vue.set(t,'__selected',false);
                    }
                })
            }
            let selectedItems = this.data.filter(t=>{
                return t.__selected;
            })
            this.$emit('selectChanged',selectedItems);
        },
        checkItem(item){
            // Vue.set(item,'__checked',!item.__checked);
            let checkItems = this.data.filter(t=>{
                return t.__checked;
            })
            this.$emit('checkChanged',checkItems);
        },
        dblclick(e,item,column,indexC){
            if(column.editable){
                if(typeof item[indexC]== 'undefined'){
                Vue.set(item,indexC,{});
                }
                Vue.set(item[indexC],'__editing',true)
                this.$emit('dblclick',item,column,indexC);   
            }
        },
        blur(item,column,index)
        {
            item[index].__editing=false;
        },
        getRowStyle(item,indexR){
            if(this.rowClass){
                return this.rowClass(item, indexR);
            }
            return item.__selected?'rowSelected':'';
        },
        updateScrollBar(){
            this.$nextTick(()=>{
                const contentHeight =  this.$refs.tableContainer.clientHeight-this.$refs.titlerow.clientHeight
                const allHeight = this.rowHeight * this.data.length;
                if(allHeight > contentHeight){
                    this.isVerticalScroll = true;
                    this.shownums = Math.ceil(contentHeight/this.rowHeight);
                    this.localData = this.data.slice(this.showStartIndex,this.showStartIndex+this.shownums)
                    this.$refs.tableEle.style.height = 'auto';
                }else{
                    this.isVerticalScroll = false;
                    this.shownums = this.data.length;
                    this.localData = this.data.slice(this.showStartIndex,this.showStartIndex+this.shownums)
                    this.$refs.tableEle.style.height = allHeight + 'px';
                }
                console.log('updateScrollBar',this.isVerticalScroll);
                this.$nextTick(()=>{
                    const scrollbar = this.$refs.scrollbar;
                    if(!scrollbar || !this.isVerticalScroll)
                    {
                        return;
                    }
                    scrollbar.style.display = 'block';
                    scrollbar.style.top = this.$refs.titlerow.clientHeight + 'px';
                    scrollbar.style.height = contentHeight + 'px';
                    scrollbar.style.width = this.$refs.titlerow.lastChild.offsetWidth + 'px';
                    const rowHeight = this.rowHeight;
                    const rowNum = Math.ceil(contentHeight/rowHeight);
                    this.shownums = rowNum;                    
                })

            })
         }
    }
}
</script>

<style scoped>

.rows:hover{
    outline: 2px solid var(--theme-primary-color);
    outline-offset: -2px;
}
table,
th,
td {
  border: 0.4px solid var(--theme-primary-color);
  text-align: center;
}

th:not(:last-child){
  border-right: 0.5px solid var(--theme-obprimary-color);
}
.rowSelected{
  background: var(--theme-highlight-color);
}
.tableEle{
    border-spacing: 0;
    position: relative;
}
.scrollbar-right{
    display: block;
    position: absolute;
    right: 0;
    background-color: rebeccapurple;
}
.title{
    background: var(--theme-primary-color);    
    color: var(--theme-obprimary-color);
    height: 20px;
    max-height: 30px;
}
.tbodyclass{
    transform: translateY();
}
</style>